package com.atguigu.product.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.atguigu.common.constant.ProductConstant;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;
import com.atguigu.product.dao.AttrAttrgroupRelationDao;
import com.atguigu.product.dao.AttrDao;
import com.atguigu.product.dao.AttrGroupDao;
import com.atguigu.product.dao.CategoryDao;
import com.atguigu.product.entity.AttrAttrgroupRelationEntity;
import com.atguigu.product.entity.AttrEntity;
import com.atguigu.product.entity.AttrGroupEntity;
import com.atguigu.product.entity.CategoryEntity;
import com.atguigu.product.vo.AttrGroupRelationVO;
import com.atguigu.product.vo.AttrRespVO;
import com.atguigu.product.vo.AttrVO;
import com.atguigu.product.service.AttrService;
import com.atguigu.product.service.CategoryService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;


@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {

    @Resource
    AttrAttrgroupRelationDao relationDao;

    @Resource
    AttrGroupDao attrGroupDao;
    @Resource
    CategoryDao categoryDao;

    @Resource
    CategoryService categoryService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrEntity> page = this.page(new Query<AttrEntity>().getPage(params), new QueryWrapper<AttrEntity>());

        return new PageUtils(page);
    }

    @Transactional
    @Override
    public void saveAttr(AttrVO attr) {
        AttrEntity attrEntity = BeanUtil.copyProperties(attr, AttrEntity.class);

        save(attrEntity);
        if (Objects.equals(attrEntity.getAttrType(), ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()) && attr.getAttrGroupId() != null) {
            //保存关联关系
            AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
            relationEntity.setAttrId(attr.getAttrId()).setAttrGroupId(attr.getAttrGroupId());
            relationDao.insert(relationEntity);
        }


    }

    @Override
    public PageUtils queryBaseAttrPage(Map<String, Object> params, Long catelogId, String type) {
        LambdaQueryWrapper<AttrEntity> wrapper = new LambdaQueryWrapper<>();

        if (catelogId != 0) {
            wrapper.eq(AttrEntity::getAttrId, catelogId).eq(AttrEntity::getAttrType, type);
        }

        String key = (String) params.get("key");
        wrapper.and(StrUtil.isNotEmpty(key), w -> w.eq(AttrEntity::getAttrId, key).like(AttrEntity::getAttrName, "base".equalsIgnoreCase(type) ? 1 : 0));
        IPage<AttrEntity> page = page(new Query<AttrEntity>().getPage(params), wrapper);
        List<AttrEntity> records = page.getRecords();
        List<AttrRespVO> attrRespVOS = records.stream().map(a -> {
            AttrRespVO attrRespVO = BeanUtil.copyProperties(a, AttrRespVO.class);
            //设置分类和分组的名字
            if ("base".equalsIgnoreCase(type)) {
                AttrAttrgroupRelationEntity attrId = relationDao.selectOne(new LambdaQueryWrapper<AttrAttrgroupRelationEntity>().eq(AttrAttrgroupRelationEntity::getAttrId, a.getAttrId()));
                if (ObjectUtil.isNotEmpty(attrId) && attrId.getAttrGroupId() != null) {
                    attrRespVO.setGroupName(attrGroupDao.selectById(attrId.getAttrGroupId()).getAttrGroupName());
                }
            }

            CategoryEntity categoryEntity = categoryDao.selectById(a.getCatelogId());
            if (ObjectUtil.isNotEmpty(categoryEntity) && StrUtil.isNotEmpty(categoryEntity.getName())) {
                attrRespVO.setCatelogName(categoryEntity.getName());
            }
            return attrRespVO;
        }).collect(Collectors.toList());

        PageUtils pageUtils = new PageUtils(page);
        pageUtils.setList(attrRespVOS);
        return pageUtils;


    }

    @Override
    public AttrRespVO getAttrInfo(Long attrId) {
        AttrEntity byId = getById(attrId);
        AttrRespVO respVO = BeanUtil.copyProperties(byId, AttrRespVO.class);


        //设置分组信息
        if (Objects.equals(byId.getAttrType(), ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode())) {
            AttrAttrgroupRelationEntity attrAttrgroupRel = relationDao.selectOne(new LambdaQueryWrapper<AttrAttrgroupRelationEntity>().eq(AttrAttrgroupRelationEntity::getAttrId, attrId));
            if (ObjectUtil.isNotEmpty(attrAttrgroupRel)) {
                respVO.setAttrGroupId(attrAttrgroupRel.getAttrGroupId());
                AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrAttrgroupRel.getAttrGroupId());
                if (ObjectUtil.isNotEmpty(attrGroupEntity)) {
                    respVO.setGroupName(attrGroupEntity.getAttrGroupName());
                }
            }
        }


        //设置分类信息
        Long catelogId = byId.getCatelogId();
        Long[] catelogPath = categoryService.findCatelogPath(catelogId);
        respVO.setCatelogPath(catelogPath);
        CategoryEntity categoryEntity = categoryDao.selectById(catelogId);
        if (ObjectUtil.isNotEmpty(categoryEntity)) {
            respVO.setCatelogName(categoryEntity.getName());
        }
        return respVO;

    }

    @Transactional
    @Override
    public void updateAttr(AttrVO attr) {
        AttrEntity attrEntity = BeanUtil.copyProperties(attr, AttrEntity.class);
        updateById(attrEntity);

        if (Objects.equals(attrEntity.getAttrType(), ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode())) {
            AttrAttrgroupRelationEntity attrAttrgroupRelation = new AttrAttrgroupRelationEntity();
            attrAttrgroupRelation.setAttrId(attr.getAttrId()).setAttrGroupId(attr.getAttrGroupId());

            Integer count = relationDao.selectCount(new LambdaQueryWrapper<AttrAttrgroupRelationEntity>().eq(AttrAttrgroupRelationEntity::getAttrId, attr.getAttrId()));
            if (count > 0) {
                //修改分组关联
                relationDao.update(attrAttrgroupRelation, new LambdaUpdateWrapper<AttrAttrgroupRelationEntity>().eq(AttrAttrgroupRelationEntity::getAttrId, attr.getAttrId()));
            } else {
                relationDao.insert(attrAttrgroupRelation);
            }

        }
    }

    /**
     * 根据分组id查询相关的所有属性
     *
     * @param attrGroupId
     * @return
     */
    @Override
    public List<AttrEntity> getRelationAttrList(Long attrGroupId) {
        List<AttrAttrgroupRelationEntity> entities = relationDao.selectList(new LambdaQueryWrapper<AttrAttrgroupRelationEntity>().eq(AttrAttrgroupRelationEntity::getAttrGroupId, attrGroupId));
        List<Long> attrIds = entities.stream().map(AttrAttrgroupRelationEntity::getAttrId).collect(Collectors.toList());
        return (List<AttrEntity>) listByIds(attrIds);
    }

    @Override
    public void deleteRelation(List<AttrGroupRelationVO> vos) {

        List<AttrAttrgroupRelationEntity> relationEntities = vos.stream().map(v -> BeanUtil.copyProperties(v, AttrAttrgroupRelationEntity.class)).collect(Collectors.toList());

        relationDao.deleteBatchRelation(relationEntities);
    }

    /**
     * 获取当前分组没有关联的所有属性
     *
     * @param attrGroupId
     * @param params
     * @return
     */
    @Override
    public PageUtils getNoRelationAttr(Long attrGroupId, Map<String, Object> params) {
        //1.当前分组只能关联自己所属的分类里面的所有属性
        AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrGroupId);
        Long catelogId = attrGroupEntity.getCatelogId();

        //2.当前分组只能关联别的分组没有引用的属性
        List<AttrGroupEntity> attrGroupEntities = attrGroupDao.selectList(new LambdaQueryWrapper<AttrGroupEntity>().eq(AttrGroupEntity::getCatelogId, catelogId));
        Set<Long> attrGroupIds = attrGroupEntities.stream().map(AttrGroupEntity::getAttrGroupId).collect(Collectors.toSet());

        List<AttrAttrgroupRelationEntity> relationEntities = relationDao.selectList(new LambdaQueryWrapper<AttrAttrgroupRelationEntity>().in(AttrAttrgroupRelationEntity::getAttrGroupId, attrGroupIds));
        Set<Long> attrIds = relationEntities.stream().map(AttrAttrgroupRelationEntity::getAttrId).collect(Collectors.toSet());

        LambdaQueryWrapper<AttrEntity> wrapper = new LambdaQueryWrapper<AttrEntity>().eq(AttrEntity::getCatelogId, catelogId).eq(AttrEntity::getAttrType, ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()).notIn(CollUtil.isNotEmpty(attrIds), AttrEntity::getAttrId, attrIds);

        String key = (String) params.get("key");
        wrapper.and(StrUtil.isNotEmpty(key), w -> w.eq(AttrEntity::getAttrId, key).or().like(AttrEntity::getAttrName, key));

        return new PageUtils(page(new Query<AttrEntity>().getPage(params), wrapper));
    }




}